/**
 * @file tcp_server_app_pdu.c
 * @brief TcpApp PDU processing
 * @Author: aple
 * @Date: 2025-9-27 9:20:10
 * @LastEditors: aple
 * @LastEditTime: 2025-9-27 18:37:50
 * @Verision: 1.0.0.0
 **/

// Switch to the appropriate trace level
#define TRACE_LEVEL TCP_APP_TRACE_LEVEL

// Dependencies
#include "server/tcp_server_app.h"
#include "server/tcp_server_app_adu.h"
#include "server/tcp_server_app_misc.h"
#include "debug.h"

/**
 * @brief Process TcpApp request
 * @param[in] connection Pointer to the client connection
 * @return Error code
 **/
error_t TcpAppServerProcessRequest(TcpAppClientConnection *connection)
{
   error_t error = NO_ERROR;
   size_t requestLen;
   size_t responseLen;
   void *request;
   void *response;
   TcpAppServerContext *context;

   // Point to the TcpApp/TCP server context
   context = connection->context;
   // Point to the TcpApp request PDU
   request = connection->requestAdu;
   requestLen = connection->requestAduLen;

   // Malformed request?
   if (requestLen == 0)
      return ERROR_INVALID_LENGTH;

   // Any registered callback?
   if (context->settings.processAduCallback != NULL)
   {
      // Point to the TcpApp response PDU
      response = connection->responseAdu;
      // Initialize response length
      responseLen = 0;

      // Process request PDU
      error = context->settings.processAduCallback(connection, request,requestLen, response, &responseLen);

      // Check status code
      if (!error)
      {
         // Valid response PDU?
         if (responseLen > 0)
         {
            // Compute the length of the response ADU
            connection->responseAduLen = responseLen;
            // Rewind to the beginning of the transmit buffer
            connection->responseAduPos = 0;
            // Send the response ADU to the client
            connection->state = TCP_APP_CONNECTION_STATE_SEND;

            error = NO_ERROR;
         }
      }
   }
   else
   {
      // response resorce
      memcpy(connection->responseAdu, connection->requestAdu, connection->requestAduLen);
      connection->responseAduLen = connection->requestAduLen;
      connection->responseAduPos = 0;
      connection->state = TCP_APP_CONNECTION_STATE_SEND;
      error = NO_ERROR;
   }

   // Any exception
   if (error == ERROR_INVALID_FUNCTION_CODE ||
       error == ERROR_INVALID_ADDRESS ||
       error == ERROR_INVALID_VALUE ||
       error == ERROR_WRITE_FAILED ||
       error == ERROR_READ_FAILED ||
       error == ERROR_DEVICE_BUSY)
   {
      // Total number of exception errors
      context->exceptionErrorCount++;
      // send except adu
      {
      }
      // Send an exception response to the TcpApp/TCP client
      error = NO_ERROR;
   }

   // Return status code
   return error;
}

